﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using SocialLearning.CoreInterfaces;

namespace ArchitectureV2
{
    public class UserModule
    {
        #region Fields

        private I_CMA_ModuleImplementation instance;
        private Dictionary<string, MethodInfo> methodCache;

        #endregion

        #region Constructor

        public UserModule(I_CMA_ModuleImplementation instance)
        {
            this.instance = instance;
            methodCache = new Dictionary<string, MethodInfo>();
            foreach (MethodInfo method in instance.GetType().GetMethods())
            {
                methodCache[method.Name] = method;
            }
            foreach (MethodInfo method in typeof(I_CMA_ModuleImplementation).GetMethods())
            {
                if (methodCache.ContainsKey(method.Name))
                {
                    methodCache.Remove(method.Name);
                }
            }
        }

        ~UserModule() { Unload(); }

        #endregion

        #region Properties

        public I_CMA_ModuleImplementation Instance { get { return (instance); } }

        public string[] MethodList { get { lock (instance) { return (methodCache.Keys.ToArray()); } } }

        #endregion

        #region Public Methods

        public void Unload()
        {
            lock (instance)
            {
                if (methodCache != null)
                {
                    try { instance.UnloadModule(); } catch { }
                    methodCache = null;
                }
            }
        }

        public MethodInfo GetMethod(string method)
        {
            lock (instance)
            {
                MethodInfo info;
                if (methodCache == null) { return (null); }
                if (methodCache.TryGetValue(method, out info) == false) { return (null); }
                return (info);
            }
        }

        public object InvokeMethod(string method, params object[] parameters)
        {
            lock (instance)
            {
                MethodInfo info;
                if (methodCache == null) { throw new Exception("Module not loaded!"); }
                if (methodCache.TryGetValue(method, out info) == false)
                {
                    throw new Exception(String.Format("Method {0} not found!", method));
                }
                return (info.Invoke(instance, parameters));
            }
        }

        #endregion
    }
}